package com.artisan.service.admin.impl;

import com.artisan.common.enums.OrderStateEnum2;
import com.artisan.common.pojo.PageBean;
import com.artisan.common.utils.TimeFormatUtil;
import com.artisan.dao.*;
import com.artisan.medium.admin.service.OrderOverViewService;
import com.artisan.medium.admin.service.WorkerService;
import com.artisan.model.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.text.DecimalFormat;
import java.util.*;

/**
 * Created by szw on 2017/6/29.
 */
@Service("orderOverViewService")
@Transactional
public class OrderOverViewServiceImpl implements OrderOverViewService {

    private static final DecimalFormat format = new DecimalFormat("##0.00");

    @Autowired
    private CustomerOrderinfoMapper customerOrderinfoMapper;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private AddressMapper addressMapper;

    @Autowired
    private AddressInfosMapper addressInfosMapper;

    @Autowired
    private BusinessMapper businessMapper;

    @Autowired
    private BusinessTypeMapper businessTypeMapper;

    @Autowired
    private WorkerMapper workerMapper;

    @Autowired
    private CustomerScoreMapper customerScoreMapper;

    @Autowired
    private AssessLableMapper assessLableMapper;

    @Autowired
    private BusinessWorkerMapper businessWorkerMapper;

    @Autowired
    private WorkerAreaMapper workerAreaMapper;

    @Override
    public Map<String, Object> orderStatistics() {
        Map<String, Object> result = new HashMap<>();

        //查询订单总数
        CustomerOrderinfoExample totalExample = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria totalCriteria = totalExample.createCriteria();
        totalCriteria.andIsdeleteEqualTo(false);
        int totalNum = customerOrderinfoMapper.countByExample(totalExample);
        result.put("totalOrders", totalNum);

        //当天订单数量
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date startTime = calendar.getTime();
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        Date endTime = calendar.getTime();
        CustomerOrderinfoExample todayExample = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria todayCriteria = todayExample.createCriteria();
        todayCriteria.andCrtTimeGreaterThanOrEqualTo(startTime)
                .andCrtTimeLessThan(endTime)
                .andIsdeleteEqualTo(false);
        int todayNum = customerOrderinfoMapper.countByExample(todayExample);
        result.put("todayOrders", todayNum);

        //代付款订单数量
        CustomerOrderinfoExample unpayExample = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria unpayCriteria = unpayExample.createCriteria();
        unpayCriteria.andStateEqualTo(OrderStateEnum2.WAITING_PAY.getValue())
                .andIsdeleteEqualTo(false);
        int waitPay = customerOrderinfoMapper.countByExample(unpayExample);
        result.put("unpayOrders", waitPay);

        //待派单订单数量
        CustomerOrderinfoExample payedExample = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria payedCriteria = payedExample.createCriteria();
        payedCriteria.andStateEqualTo(OrderStateEnum2.WAITING_ORDER.getValue())
                .andIsdeleteEqualTo(false);
        int payedNum = customerOrderinfoMapper.countByExample(payedExample);
        result.put("payedOrders", payedNum);

        //待结算订单数量
        CustomerOrderinfoExample waitSettlementExample = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria waitSettlementCriteria = waitSettlementExample.createCriteria();
        waitSettlementCriteria.andStateEqualTo(OrderStateEnum2.FINISHED.getValue())
                .andIsdeleteEqualTo(false);
        int waitSettlement = customerOrderinfoMapper.countByExample(waitSettlementExample);
        result.put("waitSettlement", waitSettlement);

        //待退款订单数量
        CustomerOrderinfoExample waitRefundExample = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria waitRefundCriteria = waitRefundExample.createCriteria();
        waitRefundCriteria.andStateEqualTo(OrderStateEnum2.IN_AUDIT.getValue())
                .andIsdeleteEqualTo(false);
        int waitRefund = customerOrderinfoMapper.countByExample(waitRefundExample);
        result.put("waitRefundOrders", waitRefund);

        /*CustomerOrderinfoExample example = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria criteria = example.createCriteria();
        criteria.andIsdeleteEqualTo(false);*/
        return result;
    }

    /**
     * 订单查询
     * @param orderNo
     * @param phone
     * @param busaId
     * @param busbId
     * @param buscId
     * @param startTime
     * @param endTime
     * @param state
     * @param provId
     * @param cityId
     * @param areaId
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageBean queryOrders(String orderNo, String phone, Integer busaId, Integer busbId, Integer buscId, String startTime,
                                String endTime, Integer state, String provId, String cityId, String areaId,
                                Integer page, Integer pageSize) {

        //一级业务类型
        List<Map<String, Object>> orderList = new ArrayList<>();
        /*List<BusinessType> businessTypeList = businessTypeMapper.selectByExample(null);
        result.put("busType", businessTypeList);*/
        //省级列表
        /*AddressInfosExample addressInfosExample = new AddressInfosExample();
        AddressInfosExample.Criteria addrCriteria = addressInfosExample.createCriteria();
        addrCriteria.andPidEqualTo("0");
        List<AddressInfos> provinces = addressInfosMapper.selectByExample(addressInfosExample);
        result.put("provinces", provinces);*/
        //查询用户
        Customer customer = null;
        if (StringUtils.isNotBlank(phone)) {
            CustomerExample customerExample = new CustomerExample();
            CustomerExample.Criteria customerCriteria = customerExample.createCriteria();
            customerCriteria.andPhoneEqualTo(phone);
            List<Customer> customers = customerMapper.selectByExample(customerExample);
            if (customers != null && customers.size() > 0) {
                customer = customers.get(0);
            } else {
                return new PageBean(page, pageSize, 0, new ArrayList<>());
            }
        }
        //设置地址条件
        List<Integer> addrIds = null;//new ArrayList<>();
        AddressExample addressExample = new AddressExample();
        AddressExample.Criteria addrCriteria2 = null;
        if (StringUtils.isNotBlank(areaId) && !"-1".equals(areaId)) {
            addrCriteria2 = addressExample.createCriteria();
            addrCriteria2.andAreaIdEqualTo(areaId);
        } else if (StringUtils.isNotBlank(cityId) && !"-1".equals(cityId)) {
            addrCriteria2 = addressExample.createCriteria();
            addrCriteria2.andCityIdEqualTo(cityId);
        } else if (StringUtils.isNotBlank(provId) && !"-1".equals(provId)) {
            addrCriteria2 = addressExample.createCriteria();
            addrCriteria2.andProvinceIdEqualTo(provId);
        }
        if (addrCriteria2 != null) {
            List<Address> addrs = addressMapper.selectByExample(addressExample);
            if (addrs != null && addrs.size() > 0) {
                addrIds = new ArrayList<>();
                for (Address add : addrs) {
                    addrIds.add(add.getId());
                }
            } else {
                return new PageBean(page, pageSize, 0, new ArrayList<>());
            }
        }
        //设置业务类型条件
        List<String> busIds = null;
        BusinessExample businessExample = new BusinessExample();
        BusinessExample.Criteria businessCriteria = null;//businessExample.createCriteria();
        BusinessTypeExample busTypeExample = new BusinessTypeExample();
        BusinessTypeExample.Criteria busTypeCriteria = null;
        if (buscId != null && buscId > 0) {
            busIds = new ArrayList<>();
            busIds.add(String.valueOf(buscId));
        } else if (busbId != null && busbId > 0) {
            businessCriteria = businessExample.createCriteria();
            businessCriteria.andPidEqualTo(busbId);
            List<Business> buses = businessMapper.selectByExample(businessExample);
            busIds = new ArrayList<>();
            if (buses != null && buses.size() > 0) {
                for (Business b : buses) {
                    busIds.add(String.valueOf(b.getId()));
                }
            }
        } else if (busaId != null && busaId > 0) {

            List<Integer> businessIds = businessMapper.queryBusIdsByBusTypeId(busaId);
            busIds = new ArrayList<>();
            if (businessIds != null && businessIds.size() > 0) {
                for (Integer id : businessIds) {
                    busIds.add(String.valueOf(id));
                }
            }
        }
        if (busIds != null && busIds.isEmpty()) {
            return new PageBean(page, pageSize, 0, new ArrayList<>());
        }
        CustomerOrderinfoExample orderinfoExample = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria orderInfoCriteria = orderinfoExample.createCriteria();
        orderInfoCriteria.andIsdeleteEqualTo(false);
        if (StringUtils.isNotBlank(orderNo)) {
            orderInfoCriteria.andOrderNoEqualTo(orderNo);
        }
        if (customer != null) {
            orderInfoCriteria.andUserIdEqualTo(customer.getId());
        }
        if (busIds != null) {
            orderInfoCriteria.andBidsIn(busIds);
        }
        if (StringUtils.isNotBlank(startTime)) {
            orderInfoCriteria.andCrtTimeGreaterThanOrEqualTo(TimeFormatUtil.parseDate(startTime));
        }
        if (StringUtils.isNotBlank(endTime)) {
            orderInfoCriteria.andCrtTimeLessThanOrEqualTo(TimeFormatUtil.parseDate(endTime + " 23:59:59"));
        }
        if (state != null && state > 0) {
            orderInfoCriteria.andStateEqualTo(state);
        }
        if (addrIds != null) {
            orderInfoCriteria.andAIdIn(addrIds);
        }
        orderinfoExample.setLimitStart((page - 1)*pageSize);
        orderinfoExample.setPageSize(pageSize);
        orderinfoExample.setOrderByClause("update_time desc");

        List<CustomerOrderinfo> orderinfos = customerOrderinfoMapper.selectByExample(orderinfoExample);
        int totalCount = customerOrderinfoMapper.countByExample(orderinfoExample);
        if (orderinfos != null && orderinfos.size() > 0) {
            for (CustomerOrderinfo order : orderinfos) {
                Map<String, Object> map = new HashMap<>();
                if (customer != null) {
                    map.put("uname", customer.getPhone());
                    //map.put("uphone", customer.getPhone());
                } else {
                    Customer customer2 = customerMapper.selectByPrimaryKey(order.getUserId());
                    if (customer2 != null) {
                        map.put("uname", customer2.getPhone());
                        //map.put("uphone", customer.getPhone());
                    }
                }
                //订单地址和用户信息
                //getAddress(order.getaId(), map);
                //map.put("address", addr);
                String busName = getBusinessName(Integer.parseInt(order.getBids()));
                map.put("bName", busName);
                map.put("orderNo", order.getOrderNo());
                map.put("price", format.format(order.getMoney()));
                map.put("state", OrderStateEnum2.getByValue(order.getState().toString()).getaState());
                map.put("stateValue", order.getState());
                map.put("crtTime", TimeFormatUtil.dateToStrFull(order.getCrtTime()));
                Map<String, Object> operate = new HashMap<>();
                operate.put("orderNo", order.getOrderNo());
                operate.put("stateValue", order.getState());
                operate.put("orderId", order.getId());
                map.put("operate", operate);
                orderList.add(map);
            }
        }

        PageBean<List<Map<String, Object>>> pageBean = new PageBean<>(page, pageSize, totalCount, orderList);
        return pageBean;
    }

    private void getAddress(Integer id, Map<String, Object> map) {
        Address address = addressMapper.selectByPrimaryKey(id);
        StringBuffer sb = new StringBuffer();
        if (address != null) {
            AddressInfos province = addressInfosMapper.selectByPrimaryKey(address.getProvinceId());
            if (province != null) {
                sb.append(province.getName());
            }
            AddressInfos city = addressInfosMapper.selectByPrimaryKey(address.getCityId());
            if (city != null) {
                sb.append(city.getName());
            }
            AddressInfos area = addressInfosMapper.selectByPrimaryKey(address.getAreaId());
            if (area != null) {
                sb.append(area.getName());
            }
            if (StringUtils.isNotBlank(address.getStreetId())) {
                AddressInfos street = addressInfosMapper.selectByPrimaryKey(address.getStreetId());
                if (street != null) {
                    sb.append(street.getName());
                }
            }
            sb.append(address.getAddress());
            map.put("serviceAddr", sb.toString());
            map.put("aName", address.getuName());
            map.put("aPhone", address.getAphone());
        }
        //return sb.toString();
    }

    private String getBusinessName(Integer bId) {
        StringBuffer sb = new StringBuffer();
        Business business = businessMapper.selectByPrimaryKey(bId);
        if (business != null) {
            BusinessType busType1 = businessTypeMapper.selectByPrimaryKey(business.getPid());
            if (busType1 != null) {
                BusinessType busType = businessTypeMapper.selectByPrimaryKey(busType1.getPid());
                if (busType != null) {
                    sb.append(busType.getbName()).append("-");
                }
                sb.append(busType1.getbName()).append("-");
            }
            sb.append(business.getbName());
        }
        return sb.toString();
    }

    /**
     * 查询订单详情
     * @param orderNo
     * @return
     */
    @Override
    public Map<String, Object> qOrderDetail(String orderNo) {
        Map<String, Object> result = new HashMap<>();
        CustomerOrderinfoExample orderinfoExample = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria orderCriteria = orderinfoExample.createCriteria();
        orderCriteria.andOrderNoEqualTo(orderNo);
        List<CustomerOrderinfo> orders = customerOrderinfoMapper.selectByExample(orderinfoExample);
        CustomerOrderinfo orderinfo = null;
        if (orders != null && orders.size() > 0) {
            orderinfo = orders.get(0);
            Map<String, Object> userMap = new HashMap<>();
            Customer customer = customerMapper.selectByPrimaryKey(orderinfo.getUserId());
            userMap.put("cphone", customer.getPhone());
            userMap.put("wxName", customer.getwName());
            result.put("customer", userMap);

            //订单信息
            Map<String, Object> orderInfo = new HashMap<>();
            getAddress(orderinfo.getaId(), orderInfo);
            String bName = getBusinessName(Integer.parseInt(orderinfo.getBids()));
            orderInfo.put("bName", bName);
            orderInfo.put("orderNo", orderinfo.getOrderNo());
            orderInfo.put("state", OrderStateEnum2.getByValue(orderinfo.getState().toString()).getaState());
            orderInfo.put("stateValue", orderinfo.getState());
            orderInfo.put("message", orderinfo.getMessage());
            orderInfo.put("price", orderinfo.getMoney());
            orderInfo.put("serviceTime", TimeFormatUtil.dateToStrFull(orderinfo.getServiceTime()));
            orderInfo.put("crtTime", TimeFormatUtil.dateToStrFull(orderinfo.getCrtTime()));
            result.put("orderInfo", orderInfo);

            //工人信息
            if (orderinfo.getwUid() != null && orderinfo.getwUid() > 0) {
                Map<String, Object> workerInfo = new HashMap<>();
                Worker worker = getWorkerInfo(orderinfo.getwUid());
                if (worker != null) {
                    workerInfo.put("wName", worker.getwName());
                    workerInfo.put("wPhone", worker.getPhone());
                    workerInfo.put("wLogo", worker.getLogo());
                    String star = getStars(worker.getId());
                    workerInfo.put("star", star);
                    result.put("worker", workerInfo);
                }
                if (orderinfo.getState() == OrderStateEnum2.FINISHED.getValue()) {
                    getScoreInfo(orderinfo.getOrderNo(), result);
                }

            }

        }
        return result;
    }

    /**
     * 获取师傅星级，师傅星级为最近评价的十单订单的评分平均值
     * @return
     */
    private String getStars(Integer wId) {
        CustomerScoreExample example = new CustomerScoreExample();
        CustomerScoreExample.Criteria criteria = example.createCriteria();
        criteria.andWIdEqualTo(wId);
        example.setLimitStart(0);
        example.setPageSize(10);
        example.setOrderByClause("ASSESS_TIME desc");

        List<CustomerScore> scores = customerScoreMapper.selectByExample(example);
        if (scores != null && scores.size() > 0) {
            int score = 0;
            for (CustomerScore cs : scores) {
                score += cs.getStars();
            }
            double avgScore = score/scores.size();
            return format.format(avgScore);
        } else {
            return "5.0";
        }
    }

    private void getScoreInfo(String orderNo, Map<String, Object> map) {
        CustomerScoreExample example = new CustomerScoreExample();
        CustomerScoreExample.Criteria criteria = example.createCriteria();
        criteria.andOrderNoEqualTo(orderNo);
        List<CustomerScore> scores = customerScoreMapper.selectByExample(example);
        if (scores != null && scores.size() > 0) {
            Map<String, Object> scoreMap = new HashMap<>();
            CustomerScore score = scores.get(0);
            scoreMap.put("star", score.getStars());
            scoreMap.put("message", score.getMessage());
            StringBuffer sb = new StringBuffer();
            if (StringUtils.isNotBlank(score.getLableIds())) {
                String[] ids = score.getLableIds().split(",");
                for (String id : ids) {
                    AssessLable al = assessLableMapper.selectByPrimaryKey(Integer.parseInt(id));
                    sb.append(al.getName()).append("、");
                }
                String lable = sb.toString().substring(0, sb.toString().lastIndexOf("、"));
                scoreMap.put("lables", lable);
            }
            map.put("assess", scoreMap);
        }
    }

    /**
     * 查询业务类型
     * @param pid
     * @param tag
     * @return
     */
    @Override
    public List<Business> qBusiness(Integer pid, String tag) {
        BusinessExample example = new BusinessExample();
        BusinessExample.Criteria criteria = example.createCriteria();
        if ("B".equals(tag)) {
            criteria.andPidEqualTo(0);
        } else {
            criteria.andPidEqualTo(pid);
        }
        List<Business> businesses = businessMapper.selectByExample(example);
        return businesses;
    }

    /**
     *
     * @param pid
     * @return
     */
    @Override
    public List<AddressInfos> qAddress(String pid) {
        AddressInfosExample example = new AddressInfosExample();
        AddressInfosExample.Criteria criteria = example.createCriteria();
        criteria.andPidEqualTo(pid);
        List<AddressInfos> addressInfos = addressInfosMapper.selectByExample(example);
        return addressInfos;
    }

    public Worker getWorkerInfo(Integer workerId) {
        Worker worker = workerMapper.selectByPrimaryKey(workerId);
        return worker;
    }

    @Override
    public List<Worker> queryWorkers(String orderNo) {
        CustomerOrderinfoExample orderinfoExample = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria orderInfoCriteria = orderinfoExample.createCriteria();
        orderInfoCriteria.andOrderNoEqualTo(orderNo);
        List<CustomerOrderinfo> orderinfos = customerOrderinfoMapper.selectByExample(orderinfoExample);
        if (orderinfos != null && orderinfos.size() > 0) {
            //下单地址
            Address address = addressMapper.selectByPrimaryKey(orderinfos.get(0).getaId());
            String areaId = address.getAreaId();
            WorkerAreaExample areaExample = new WorkerAreaExample();
            WorkerAreaExample.Criteria areaCriteria = areaExample.createCriteria();
            areaCriteria.andAreaIdEqualTo(areaId);
            List<WorkerArea> workerAreas = workerAreaMapper.selectByExample(areaExample);
            List<Integer> wids1 = new ArrayList<>();
            if (workerAreas != null && workerAreas.size() > 0) {
                for (WorkerArea wa : workerAreas) {
                    wids1.add(wa.getwId());
                }
            }
            //订单业务类型
            String bid = orderinfos.get(0).getBids();
            List<Integer> workerIds = new ArrayList<>();
            if (StringUtils.isNotBlank(bid)) {
                Business business = businessMapper.selectByPrimaryKey(Integer.parseInt(bid));
                if (business != null) {
                    BusinessType bt = businessTypeMapper.selectByPrimaryKey(business.getPid());
                    BusinessWorkerExample workerExample = new BusinessWorkerExample();
                    BusinessWorkerExample.Criteria bwCriteria = workerExample.createCriteria();
                    bwCriteria.andBIdEqualTo(bt.getbId());
                    List<BusinessWorker> bws = businessWorkerMapper.selectByExample(workerExample);

                    if (bws != null && bws.size() > 0) {
                        for (BusinessWorker bw : bws) {
                            workerIds.add(bw.getwId());
                        }
                    }
                }
            }
            wids1.retainAll(workerIds);
            if (wids1.size() > 0) {
                WorkerExample workerExample = new WorkerExample();
                WorkerExample.Criteria criteria = workerExample.createCriteria();
                criteria.andIdIn(wids1);
                List<Worker> workers = workerMapper.selectByExample(workerExample);
                if (workers != null) {
                    return workers;
                }
            }
        }
        return null;
    }

    @Override
    public int disPatchOrder(String orderNo, Integer workerId) {
        CustomerOrderinfoExample example = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria criteria = example.createCriteria();
        criteria.andOrderNoEqualTo(orderNo);
        List<CustomerOrderinfo> orderinfos = customerOrderinfoMapper.selectByExample(example);
        if (orderinfos != null && orderinfos.size() > 0) {
            CustomerOrderinfo order = orderinfos.get(0);
            order.setUpdateTime(new Date());
            order.setState(OrderStateEnum2.ALREADY_ORDER.getValue());
            order.setwUid(workerId);
            return customerOrderinfoMapper.updateByPrimaryKeySelective(order);
        }
        return 0;
     }

    @Override
    public int confirmOrderFinished(String orderNo) {
        CustomerOrderinfoExample example = new CustomerOrderinfoExample();
        CustomerOrderinfoExample.Criteria criteria = example.createCriteria();
        criteria.andOrderNoEqualTo(orderNo);
        List<CustomerOrderinfo> orderinfos = customerOrderinfoMapper.selectByExample(example);
        if (orderinfos != null && orderinfos.size() > 0) {
            CustomerOrderinfo order = orderinfos.get(0);
            order.setUpdateTime(new Date());
            order.setState(OrderStateEnum2.WAIT_CONFIRM.getValue());
            return customerOrderinfoMapper.updateByPrimaryKeySelective(order);
        }
        return 0;
    }
}
